﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using Framework.Infrastructure;
using System.Collections;
using System.Threading;

namespace Framework.Bus.LifetimeManagers
{
    public class PerMessageContextLifetimeManager
        : LifetimeManager
    {
        static Hashtable CurrentMessageContext = new Hashtable();
        Guid _key;

        public static void InitCaches()
        {
            CurrentMessageContext.Clear();
        }

        public static void ClearCaches()
        {
            foreach (var value in CurrentMessageContext.Values)
            {
                if (value is IDisposable)
                {
                    (value as IDisposable).Dispose();
                }
            }
            CurrentMessageContext.Clear();
        }

        #region Constructor

        /// <summary>
        /// Default constructor
        /// </summary>
        public PerMessageContextLifetimeManager() : this(Guid.NewGuid()) { }

        /// <summary>
        ///  Constructor
        /// </summary>
        /// <param name="key">A key for this lifetimemanager resolver</param>
        PerMessageContextLifetimeManager(Guid key)
        {
            if (key == Guid.Empty)
                throw new ArgumentException("PerExecutionContextLifetimeManagerKeyCannotBeNull");

            _key = key;
        }
        #endregion

        #region ILifetimeManager Members

        /// <summary>
        /// <see cref="M:Microsoft.Practices.Unity.LifetimeManager.GetValue"/>
        /// </summary>
        /// <returns><see cref="M:Microsoft.Practices.Unity.LifetimeManager.GetValue"/></returns>
        public override object GetValue()
        {
            object result = null;

            //Get object depending on  execution environment ( WCF without HttpContext,HttpContext or CallContext)

            if (CurrentMessageContext != null)
            {
                //HttpContext avaiable ( ASP.NET ..)
                if (CurrentMessageContext[_key] != null)
                    result = CurrentMessageContext[_key];
            }

            return result;
        }
        /// <summary>
        /// <see cref="M:Microsoft.Practices.Unity.LifetimeManager.RemoveValue"/>
        /// </summary>
        public override void RemoveValue()
        {
            object value = null;
            if (CurrentMessageContext != null)
            {
                //WCF without HttpContext environment
                value = CurrentMessageContext[_key];
                if (value != null)
                {
                    CurrentMessageContext.Remove(_key);
                }
            }

            if (value is IDisposable)
            {
                (value as IDisposable).Dispose();
            }
        }
        /// <summary>
        /// <see cref="M:Microsoft.Practices.Unity.LifetimeManager.SetValue"/>
        /// </summary>
        /// <param name="newValue"><see cref="M:Microsoft.Practices.Unity.LifetimeManager.SetValue"/></param>
        public override void SetValue(object newValue)
        {
            if (CurrentMessageContext != null)
            {
                //WCF without HttpContext environment
                CurrentMessageContext.Add(_key, newValue);
            }
        }

        #endregion


    }
}
